package com.xian.im.modules.distributed;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.xian.im.modules.distributed.util.ConsistentHashingWithoutVirtualNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: xian-im-server
 * @description:
 * @author: liru.xian
 * @create: 2021-02-08 18:09
 **/
@Slf4j
@Component
@Lazy
public class ContextInstance {

    public static final String PROJECT_NAME= "xim-tcp-server";
    @NacosInjected
    private NamingService namingService;

    /**
     *  获取全部的实例
     * @return
     */
    public List<Instance> instances(){
        List<Instance> allInstances = null;
        try {
            allInstances = namingService.getAllInstances(PROJECT_NAME);
        } catch (NacosException e) {
            e.printStackTrace();
        }
        log.info("List<ServiceInfo> {} ",allInstances);
        return allInstances;
    }

    /**
     * 版本获取
     * @param version
     * @return
     */
    public List<Instance> instances(String version){
        try {
            List<Instance> instances = namingService.getAllInstances(PROJECT_NAME);
            List<Instance> versionList = instances.stream().filter(instance -> version.equals(instance.getMetadata().get("version"))).collect(Collectors.toList());
            return versionList;
        } catch (NacosException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     *
     * @param version 制定版本
     * @param mark  业务hash逻辑
     * @return
     */
    public Instance getServer(String version,String mark){
        List<Instance> instances = null;
        if(StringUtils.isNotBlank(version)){
            instances = instances(version);
        }else {
            instances = instances();
        }
        List<String> instanceIds = instances.stream().map(Instance::getInstanceId).collect(Collectors.toList());
        ConsistentHashingWithoutVirtualNode consistentHashingWithoutVirtualNode = new ConsistentHashingWithoutVirtualNode(instanceIds);
        String instanceId = consistentHashingWithoutVirtualNode.getServer(mark);
        for (Instance instance : instances) {
            if(instanceId.equals(instance.getInstanceId())){
                return instance;
            }
        }
        return null;
    }

    /**
     *
     * @param mark  业务hash逻辑
     * @return
     */
    public Instance getServer(String mark){
        return getServer(null,mark);
    }


}
